Set up

suppressPackageStartupMessages({
  library(tidyverse)
})

Directories and File Inputs/Outputs

# Detect the ".git" folder -- this will be in the project root directory
# Use this as the root directory to ensure proper sourcing of functions 
# no matter where this is called from
root_dir <- rprojroot::find_root(rprojroot::has_dir(".git"))
analysis_dir <- file.path(root_dir, "analyses", "tmb-vaf-longitudinal")
results_dir <- file.path(analysis_dir, "results")
input_dir <- file.path(analysis_dir, "input")
files_dir <- file.path(root_dir, "analyses", "sample-distribution-analysis", "results")

# Input files
genomic_paired_file <- file.path(files_dir, "genomic_assays_matched_time_points_extended.tsv") 
tmb_vaf_file <- file.path(results_dir, "tmb_vaf_genomic.tsv")
palette_file <- file.path(root_dir, "figures", "palettes", "oncoprint_color_palette.tsv")

# File path to plot directory
plots_dir <-
  file.path(analysis_dir, "plots")
if (!dir.exists(plots_dir)) {
  dir.create(plots_dir)
}

source(paste0(root_dir, "/figures/scripts/theme.R"))

Read in data and process

tmb_vaf_df <- readr::read_tsv(tmb_vaf_file, guess_max = 100000, show_col_types = FALSE) %>% 
  filter(!tmb >= 10) %>% 
  select(Kids_First_Biospecimen_ID, Variant_Classification, gene_protein, mutation_count,   region_size, tmb, VAF)

genomic_paired_df <- readr::read_tsv(genomic_paired_file, guess_max = 100000, show_col_types = FALSE) %>% 
  left_join(tmb_vaf_df, by = c(\Kids_First_Biospecimen_ID\)) %>%
  filter(!is.na(tmb)) 


# Attention as some bs specimen might not have TMB!
# If that happens, we will end up with samples lacking timepoints.

# Which patient samples don't have TMB?
# genomic_paired_df %>% 
#  filter(is.na(tmb)) %>% 
#  unique() %>% 
#  regulartable() %>%
#  fontsize(size = 12, part = \all\)

descriptors_df <- genomic_paired_df %>%
  group_by(Kids_First_Participant_ID) %>%
  summarize(descriptors = paste(sort(tumor_descriptor), collapse = \
# Read color palette
palette_df <- readr::read_tsv(palette_file, guess_max = 100000, show_col_types = FALSE) 

# Define and order palette
palette <- palette_df$hex_codes
names(palette) <- palette_df$Variant_Classification
# Define label for plots
Alteration_type <- df_plot$Variant_Classification

# Define ylim
ylim <- max(df_plot$log10_tmb)

What type of alterations we observe per tumor descriptor?

# Create bxp
print(ggpubr::ggboxplot(df_plot, 
                        x = \tumor_descriptor\, 
                        y = \log10_tmb\, 
                        color = \Variant_Classification\,
                        palette = palette) +
        theme_Publication() + 
        scale_y_continuous(limits = c(0, ylim)) +
        xlab(\Timepoint\) +
        theme(axis.text.x = element_text(angle = 90)))

# Save the plot
ggsave(filename = \Alteration_type_timepoints.pdf\, 
       path = plots_dir, 
       width = 15, 
       height = 8, 
       device = \pdf\, 
       useDingbats = FALSE)

What type of alterations we observe per tumor descriptor in each cancer group?

# Create bxp
print(ggpubr::ggboxplot(df_plot, 
                        x = \tumor_descriptor\, 
                        y = \log10_tmb\, 
                        color = \Variant_Classification\,
                        palette = palette) +
        facet_wrap(~cg_id) +
        theme_Publication() + 
        xlab(\Timepoint\) +
        scale_y_continuous(limits = c(0, ylim)) +
        theme(axis.text.x = element_text(angle = 90)))

# Save the plot
ggsave(filename = \Alteration_type_cancer_group.pdf\, 
       path = plots_dir, 
       width = 25, 
       height = 18, 
       device = \pdf\, 
       useDingbats = FALSE)

What type of alterations we observe per tumor descriptor in each cancer group defined by cgGFAC?

df_plot_cgGFAC <- df_plot %>% 
  arrange(tumor_descriptor_cgGFAC_n)
  #mutate(tumor_descriptor_cgGFAC_n = factor(tumor_descriptor_cgGFAC_n)) 

#df_plot_cgGFAC$tumor_descriptor_cgGFAC_n %>% levels()

# Create bxp
print(ggpubr::ggboxplot(df_plot_cgGFAC, 
                        x = \tumor_descriptor_cgGFAC_n\, 
                        y = \log10_tmb\, 
                        color = \Variant_Classification\,
                        palette = palette) +
        theme_Publication() + 
        xlab(\Timepoint\) +
        scale_y_continuous(limits = c(0, ylim)) +
        theme(axis.text.x = element_text(angle = 90)))

# Save the plot
ggsave(filename = \Alteration_type_cgGFAC.pdf\, 
       path = plots_dir, 
       width = 14, 
       height = 8, 
       device = \pdf\, 
       useDingbats = FALSE)
cgGFAC_id <- as.character(unique(df_plot_cgGFAC$cgGFAC))
cgGFAC_id
[1] \ATRT\  \DMG\   \HGG\   \LGG\   \Other\
ATRT

DMG

HGG

LGG

Other
# Loop through variable
for (i in seq_along(cgGFAC_id)){
  print(i)
  df_sub <- df_plot_cgGFAC %>%
      filter(cgGFAC == cgGFAC_id[i])

  
   # Create bxp
  print(ggpubr::ggboxplot(df_sub, 
                        x = \tumor_descriptor_cgGFAC_n\, 
                        y = \log10_tmb\, 
                        color = \Variant_Classification\,
                        palette = palette) +
        theme_Publication() + 
        labs(title = paste(cgGFAC_id[i])) +
        scale_y_continuous(limits = c(0, ylim)) +
        theme(axis.text.x = element_text(angle = 90, vjust = 0.5, hjust = 1)))
}
[1] 1

[1] 2

[1] 3

[1] 4

[1] 5

What type of alterations we observe per tumor descriptor in each cancer group (add _n))?

cg <- as.character(unique(df_plot$cg_id))
cg
 [1] \Embryonal tumor with multilayer rosettes\
 [2] \Low-grade glioma\                        
 [3] \Ependymoma\                              
 [4] \Medulloblastoma\                         
 [5] \Atypical Teratoid Rhabdoid Tumor\        
 [6] \Diffuse midline glioma\                  
 [7] \High-grade glioma\                       
 [8] \Ganglioglioma\                           
 [9] \Meningioma\                              
[10] \Pilocytic astrocytoma\                   
[11] \CNS Embryonal tumor\                     
[12] \Neuroblastoma\                           
[13] \Schwannoma\                              
[14] \Chordoma\                                
[15] \Malignant peripheral nerve sheath tumor\ 
[16] \Choroid plexus carcinoma\                
[17] \Adamantinomatous Craniopharyngioma\      
[18] \Dysembryoplastic neuroepithelial tumor\  
[19] \Ewing sarcoma\                           
[20] \Rosai-Dorfman disease\                   
[21] \Neurofibroma/Plexiform\                  
[22] \Glial-neuronal tumor\                    
[23] \Hemangioblastoma\                        
[24] \Craniopharyngioma\                       
Embryonal tumor with multilayer rosettes

Low-grade glioma

Ependymoma

Medulloblastoma

Atypical Teratoid Rhabdoid Tumor

Diffuse midline glioma

High-grade glioma

Ganglioglioma

Meningioma

Pilocytic astrocytoma

CNS Embryonal tumor

Neuroblastoma

Schwannoma

Chordoma

Malignant peripheral nerve sheath tumor

Choroid plexus carcinoma

Adamantinomatous Craniopharyngioma

Dysembryoplastic neuroepithelial tumor

Ewing sarcoma

Rosai-Dorfman disease

Neurofibroma/Plexiform

Glial-neuronal tumor

Hemangioblastoma

Craniopharyngioma
# Loop through variable
for (i in seq_along(cg)){
  print(i)
  df_sub <- df_plot %>%
      filter(cg_id == cg[i])
  
  # Create bxp
  print(ggpubr::ggboxplot(df_sub, 
                        x = \tumor_descriptor_cg_n\, 
                        y = \log10_tmb\, 
                        color = \Variant_Classification\,
                        palette = palette) +
        theme_Publication() + 
        xlab(\Timepoint\) +
        labs(title = paste(cg[i])) +
        scale_y_continuous(limits = c(0, ylim)) +
        theme(axis.text.x = element_text(angle = 90, vjust = 0.5, hjust = 1)))
}
[1] 1

[1] 2

[1] 3

[1] 4

[1] 5

[1] 6

[1] 7

[1] 8

[1] 9

[1] 10

[1] 11

[1] 12

[1] 13

[1] 14

[1] 15

[1] 16

[1] 17

[1] 18

[1] 19

[1] 20

[1] 21

[1] 22

[1] 23

[1] 24

What type of alterations we observe per tumor descriptor in each cancer group and timepoint model?

tm <- as.character(unique(df_plot$timepoints_models))
tm
 [1] \Dx-Rec\         \Dx-Pro\         \Dx-Dec\         \Pro-Dec\       
 [5] \Rec-SM\         \Pro-Rec\        \Dx-SM\          \Pro-Rec-Dec\   
 [9] \Dx-Pro-Rec\     \Rec-Dec\        \Dx-Pro-Rec-Dec\ \Dx-Rec-Dec\    
[13] \Dx-Pro-Dec\    
Dx-Rec

Dx-Pro

Dx-Dec

Pro-Dec

Rec-SM

Pro-Rec

Dx-SM

Pro-Rec-Dec

Dx-Pro-Rec

Rec-Dec

Dx-Pro-Rec-Dec

Dx-Rec-Dec

Dx-Pro-Dec
# Loop through variable
for (i in seq_along(tm)){
  print(i)
  df_sub <- df_plot %>%
      filter(timepoints_models == tm[i])
  
  # Create bxp
  print(ggpubr::ggboxplot(df_sub, 
                        x = \tumor_descriptor\, 
                        y = \tmb\, 
                        color = \Variant_Classification\,
                        palette = palette) +
        facet_wrap(~cancer_group) +
        theme_Publication() +
        ylab(\TMB\) +
        xlab(\Timepoint\) +
        scale_y_continuous(limits = c(0, ylim)) +
        theme(axis.text.x = element_text(angle = 90)))
}
[1] 1

[1] 2

[1] 3

[1] 4

[1] 5

[1] 6

[1] 7

[1] 8

[1] 9

[1] 10

[1] 11

[1] 12

[1] 13

sessionInfo()
R version 4.2.3 (2023-03-15)
Platform: aarch64-apple-darwin20 (64-bit)
Running under: macOS Ventura 13.5.1

Matrix products: default
BLAS:   /Library/Frameworks/R.framework/Versions/4.2-arm64/Resources/lib/libRblas.0.dylib
LAPACK: /Library/Frameworks/R.framework/Versions/4.2-arm64/Resources/lib/libRlapack.dylib

locale:
[1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8

attached base packages:
[1] grid      stats     graphics  grDevices utils     datasets  methods  
[8] base     

other attached packages:
 [1] ggthemes_4.2.4  lubridate_1.9.2 forcats_1.0.0   stringr_1.5.0  
 [5] dplyr_1.1.2     purrr_1.0.1     readr_2.1.4     tidyr_1.3.0    
 [9] tibble_3.2.1    ggplot2_3.4.2   tidyverse_2.0.0

loaded via a namespace (and not attached):
 [1] tidyselect_1.2.0  xfun_0.39         bslib_0.5.0       carData_3.0-5    
 [5] colorspace_2.1-0  vctrs_0.6.3       generics_0.1.3    htmltools_0.5.5  
 [9] yaml_2.3.7        utf8_1.2.3        rlang_1.1.1       jquerylib_0.1.4  
[13] pillar_1.9.0      ggpubr_0.6.0      glue_1.6.2        withr_2.5.0      
[17] bit64_4.0.5       lifecycle_1.0.3   munsell_0.5.0     ggsignif_0.6.4   
[21] gtable_0.3.3      ragg_1.2.5        evaluate_0.21     labeling_0.4.2   
[25] knitr_1.43        tzdb_0.4.0        fastmap_1.1.1     parallel_4.2.3   
[29] fansi_1.0.4       highr_0.10        broom_1.0.5       scales_1.2.1     
[33] backports_1.4.1   cachem_1.0.8      vroom_1.6.3       jsonlite_1.8.7   
[37] abind_1.4-5       systemfonts_1.0.4 farver_2.1.1      bit_4.0.5        
[41] textshaping_0.3.6 hms_1.1.3         digest_0.6.33     stringi_1.7.12   
[45] rstatix_0.7.2     rprojroot_2.0.3   cli_3.6.1         tools_4.2.3      
[49] magrittr_2.0.3    sass_0.4.7        crayon_1.5.2      car_3.1-2        
[53] pkgconfig_2.0.3   timechange_0.2.0  rmarkdown_2.23    R6_2.5.1         
[57] compiler_4.2.3   
LS0tCnRpdGxlOiAiQ2xhc3NpZmljYXRpb24gb2YgVmFyaWFudHMgYWNyb3NzIHBhaXJlZCBsb25naXR1ZGluYWwgc2FtcGxlcyBpbiB0aGUgUEJUQSBDb2hvcnQiCmF1dGhvcjogJ0FudG9uaWEgQ2hyb25pIDxjaHJvbmlhQGNob3AuZWR1PiBmb3IgRDNCJwpkYXRlOiAiMjAyMyIKb3V0cHV0OgogIGh0bWxfbm90ZWJvb2s6CiAgICB0b2M6IFRSVUUKICAgIHRvY19mbG9hdDogVFJVRQotLS0KCiMgU2V0IHVwCmBgYHtyIGxvYWQtbGlicmFyeX0Kc3VwcHJlc3NQYWNrYWdlU3RhcnR1cE1lc3NhZ2VzKHsKICBsaWJyYXJ5KHRpZHl2ZXJzZSkKfSkKYGBgCgojIyBEaXJlY3RvcmllcyBhbmQgRmlsZSBJbnB1dHMvT3V0cHV0cwpgYGB7ciBzZXQtZGlyLWFuZC1maWxlLW5hbWVzfQojIERldGVjdCB0aGUgIi5naXQiIGZvbGRlciAtLSB0aGlzIHdpbGwgYmUgaW4gdGhlIHByb2plY3Qgcm9vdCBkaXJlY3RvcnkKIyBVc2UgdGhpcyBhcyB0aGUgcm9vdCBkaXJlY3RvcnkgdG8gZW5zdXJlIHByb3BlciBzb3VyY2luZyBvZiBmdW5jdGlvbnMgCiMgbm8gbWF0dGVyIHdoZXJlIHRoaXMgaXMgY2FsbGVkIGZyb20Kcm9vdF9kaXIgPC0gcnByb2pyb290OjpmaW5kX3Jvb3QocnByb2pyb290OjpoYXNfZGlyKCIuZ2l0IikpCmFuYWx5c2lzX2RpciA8LSBmaWxlLnBhdGgocm9vdF9kaXIsICJhbmFseXNlcyIsICJ0bWItdmFmLWxvbmdpdHVkaW5hbCIpCnJlc3VsdHNfZGlyIDwtIGZpbGUucGF0aChhbmFseXNpc19kaXIsICJyZXN1bHRzIikKaW5wdXRfZGlyIDwtIGZpbGUucGF0aChhbmFseXNpc19kaXIsICJpbnB1dCIpCmZpbGVzX2RpciA8LSBmaWxlLnBhdGgocm9vdF9kaXIsICJhbmFseXNlcyIsICJzYW1wbGUtZGlzdHJpYnV0aW9uLWFuYWx5c2lzIiwgInJlc3VsdHMiKQoKIyBJbnB1dCBmaWxlcwpnZW5vbWljX3BhaXJlZF9maWxlIDwtIGZpbGUucGF0aChmaWxlc19kaXIsICJnZW5vbWljX2Fzc2F5c19tYXRjaGVkX3RpbWVfcG9pbnRzX2V4dGVuZGVkLnRzdiIpIAp0bWJfdmFmX2ZpbGUgPC0gZmlsZS5wYXRoKHJlc3VsdHNfZGlyLCAidG1iX3ZhZl9nZW5vbWljLnRzdiIpCnBhbGV0dGVfZmlsZSA8LSBmaWxlLnBhdGgocm9vdF9kaXIsICJmaWd1cmVzIiwgInBhbGV0dGVzIiwgIm9uY29wcmludF9jb2xvcl9wYWxldHRlLnRzdiIpCgojIEZpbGUgcGF0aCB0byBwbG90IGRpcmVjdG9yeQpwbG90c19kaXIgPC0KICBmaWxlLnBhdGgoYW5hbHlzaXNfZGlyLCAicGxvdHMiKQppZiAoIWRpci5leGlzdHMocGxvdHNfZGlyKSkgewogIGRpci5jcmVhdGUocGxvdHNfZGlyKQp9Cgpzb3VyY2UocGFzdGUwKHJvb3RfZGlyLCAiL2ZpZ3VyZXMvc2NyaXB0cy90aGVtZS5SIikpCmBgYAoKIyMgUmVhZCBpbiBkYXRhIGFuZCBwcm9jZXNzCmBgYHtyIGxvYWQtcHJvY2Vzcy1pbnB1dHN9CnRtYl92YWZfZGYgPC0gcmVhZHI6OnJlYWRfdHN2KHRtYl92YWZfZmlsZSwgZ3Vlc3NfbWF4ID0gMTAwMDAwLCBzaG93X2NvbF90eXBlcyA9IEZBTFNFKSAlPiUgCiAgZmlsdGVyKCF0bWIgPj0gMTApICU+JSAKICBzZWxlY3QoS2lkc19GaXJzdF9CaW9zcGVjaW1lbl9JRCwgVmFyaWFudF9DbGFzc2lmaWNhdGlvbiwgZ2VuZV9wcm90ZWluLCBtdXRhdGlvbl9jb3VudCwJcmVnaW9uX3NpemUsIHRtYiwgVkFGKQoKZ2Vub21pY19wYWlyZWRfZGYgPC0gcmVhZHI6OnJlYWRfdHN2KGdlbm9taWNfcGFpcmVkX2ZpbGUsIGd1ZXNzX21heCA9IDEwMDAwMCwgc2hvd19jb2xfdHlwZXMgPSBGQUxTRSkgJT4lIAogIGxlZnRfam9pbih0bWJfdmFmX2RmLCBieSA9IGMoIktpZHNfRmlyc3RfQmlvc3BlY2ltZW5fSUQiKSkgJT4lCiAgZmlsdGVyKCFpcy5uYSh0bWIpKSAKCgojIEF0dGVudGlvbiBhcyBzb21lIGJzIHNwZWNpbWVuIG1pZ2h0IG5vdCBoYXZlIFRNQiEKIyBJZiB0aGF0IGhhcHBlbnMsIHdlIHdpbGwgZW5kIHVwIHdpdGggc2FtcGxlcyBsYWNraW5nIHRpbWVwb2ludHMuCgojIFdoaWNoIHBhdGllbnQgc2FtcGxlcyBkb24ndCBoYXZlIFRNQj8KIyBnZW5vbWljX3BhaXJlZF9kZiAlPiUgCiMgIGZpbHRlcihpcy5uYSh0bWIpKSAlPiUgCiMgIHVuaXF1ZSgpICU+JSAKIyAgcmVndWxhcnRhYmxlKCkgJT4lCiMgIGZvbnRzaXplKHNpemUgPSAxMiwgcGFydCA9ICJhbGwiKQoKZGVzY3JpcHRvcnNfZGYgPC0gZ2Vub21pY19wYWlyZWRfZGYgJT4lCiAgZ3JvdXBfYnkoS2lkc19GaXJzdF9QYXJ0aWNpcGFudF9JRCkgJT4lCiAgc3VtbWFyaXplKGRlc2NyaXB0b3JzID0gcGFzdGUoc29ydCh0dW1vcl9kZXNjcmlwdG9yKSwgY29sbGFwc2UgPSAiLCAiKSwpIAoKCiMgVmVjdG9yIHRvIG9yZGVyIHRpbWVwb2ludHMKdGltZXBvaW50cyA8LSBjKCJEaWFnbm9zaXMiLCAiUHJvZ3Jlc3NpdmUiLCAiUmVjdXJyZW5jZSIsICJEZWNlYXNlZCIsICJTZWNvbmQgTWFsaWduYW5jeSIsICJVbmF2YWlsYWJsZSIpCgpkZiA8LSBnZW5vbWljX3BhaXJlZF9kZiAlPiUgCiAgbGVmdF9qb2luKGRlc2NyaXB0b3JzX2RmLCBieSA9IGMoIktpZHNfRmlyc3RfUGFydGljaXBhbnRfSUQiKSkgJT4lIAogIG11dGF0ZShjZ0dGQUMgPSBjYXNlX3doZW4oZ3JlcGwoIkhpZ2gtZ3JhZGUgZ2xpb21hIiwgY2FuY2VyX2dyb3VwKSB+ICJIR0ciLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZ3JlcGwoIkRpZmZ1c2UgbWlkbGluZSBnbGlvbWEiLCBjYW5jZXJfZ3JvdXApIH4gIkRNRyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBncmVwbCgiQXR5cGljYWwgVGVyYXRvaWQgUmhhYmRvaWQgVHVtb3IiLCBjYW5jZXJfZ3JvdXApIH4gIkFUUlQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZ3JlcGwoIkxvdy1ncmFkZSBnbGlvbWEiLCBjYW5jZXJfZ3JvdXApIH4gIkxHRyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBUUlVFIH4gIk90aGVyIiksCiAgICAgICAgIHRkX2NnR0ZBQyA9IGNhc2Vfd2hlbihncmVwbCgiRGVjZWFzZWQiLCB0dW1vcl9kZXNjcmlwdG9yKSB+ICJ4RGVjZWFzZWQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRSVUUgfiB0dW1vcl9kZXNjcmlwdG9yKSwKICAgICAgICAgbG9nMTBfdG1iID0gYWJzKGxvZzEwKHRtYikpKQoKIyBMZXQncyBjb3VudCAjc2FtcGxlcyBwZXIgY2FuY2VyIGdyb3VwcyBhbmQgdGltZXBvaW50cy4KIyBXZSB3aWxsIHVzZSB0aGUgY2dfaWQgY29sIHRoYXQgaW5kaWNhdGVzIGNhbmNlciB0eXBlIGFzIGlkZW50aWZpZWQgYXQgdGhlIGZpcnN0IGRpYWdub3N0aWMgc2FtcGxlCnRpbWVwb2ludF9jZ19uX2RmIDwtIGRmICU+JSAKICBjb3VudChjZ19pZCwgdHVtb3JfZGVzY3JpcHRvcikgJT4lIAogIGRwbHlyOjptdXRhdGUodHVtb3JfZGVzY3JpcHRvcl9jZ19uID0gZ2x1ZTo6Z2x1ZSgie2NnX2lkfV97dHVtb3JfZGVzY3JpcHRvcn0gIChOPXtufSkiKSkgJT4lIAogIGRwbHlyOjpyZW5hbWUodGltZXBvaW50X2NnX24gPSBuKSAKCiMgTGV0J3MgY291bnQgI3NhbXBsZXMgcGVyIGNhbmNlciBncm91cHMgYW5kIHRpbWVwb2ludHMgCnRpbWVwb2ludF9jZ0dGQUNfbl9kZiA8LSBkZiAlPiUgCiAgY291bnQoY2dHRkFDLCB0ZF9jZ0dGQUMpICU+JSAKICBkcGx5cjo6bXV0YXRlKHR1bW9yX2Rlc2NyaXB0b3JfY2dHRkFDX24gPSBnbHVlOjpnbHVlKCJ7Y2dHRkFDfV97dGRfY2dHRkFDfSAgKE49e259KSIpKSAlPiUgCiAgZHBseXI6OnJlbmFtZSh0aW1lcG9pbnRfY2dHRkFDX24gPSBuKSAKCiMgQ3JlYXRlIGRmIHRvIHVzZSBmb3IgcGxvdHMKZGZfcGxvdCA8LSBkZiAlPiUgCiAgbGVmdF9qb2luKHRpbWVwb2ludF9jZ19uX2RmLCBieSA9IGMoInR1bW9yX2Rlc2NyaXB0b3IiLCAiY2dfaWQiKSkgJT4lCiAgbGVmdF9qb2luKHRpbWVwb2ludF9jZ0dGQUNfbl9kZiwgYnkgPSBjKCJ0ZF9jZ0dGQUMiLCAiY2dHRkFDIikpICU+JSAKICBmaWx0ZXIoIXRpbWVwb2ludF9jZ19uIDw9IDIsCiAgICAgICAgICF0aW1lcG9pbnRfY2dHRkFDX24gPD0gMiwKICAgICAgICAgIWNnX2lkID09ICJOQSIpICU+JSAKICBtdXRhdGUodHVtb3JfZGVzY3JpcHRvciA9IGZhY3Rvcih0dW1vcl9kZXNjcmlwdG9yKSwKICAgICAgICAgdHVtb3JfZGVzY3JpcHRvciA9IGZjdF9yZWxldmVsKHR1bW9yX2Rlc2NyaXB0b3IsIHRpbWVwb2ludHMpKQogICAgICAgIApgYGAgCgoKYGBge3IgZGVmaW5lLXBhcmFtZXRlcnMtZm9yLXBsb3RzfQojIFJlYWQgY29sb3IgcGFsZXR0ZQpwYWxldHRlX2RmIDwtIHJlYWRyOjpyZWFkX3RzdihwYWxldHRlX2ZpbGUsIGd1ZXNzX21heCA9IDEwMDAwMCwgc2hvd19jb2xfdHlwZXMgPSBGQUxTRSkgCgojIERlZmluZSBhbmQgb3JkZXIgcGFsZXR0ZQpwYWxldHRlIDwtIHBhbGV0dGVfZGYkaGV4X2NvZGVzCm5hbWVzKHBhbGV0dGUpIDwtIHBhbGV0dGVfZGYkVmFyaWFudF9DbGFzc2lmaWNhdGlvbgoKIyBEZWZpbmUgbGFiZWwgZm9yIHBsb3RzCkFsdGVyYXRpb25fdHlwZSA8LSBkZl9wbG90JFZhcmlhbnRfQ2xhc3NpZmljYXRpb24KCiMgRGVmaW5lIHlsaW0KeWxpbSA8LSBtYXgoZGZfcGxvdCRsb2cxMF90bWIpCmBgYAoKIyBXaGF0IHR5cGUgb2YgYWx0ZXJhdGlvbnMgd2Ugb2JzZXJ2ZSBwZXIgdHVtb3IgZGVzY3JpcHRvcj8KCmBgYHtyIHBsb3QtdGltZXBvaW50LCBmaWcud2lkdGggPSAxNSwgZmlnLmhlaWdodCA9IDgsIGZpZy5mdWxsd2lkdGggPSBUUlVFfQojIENyZWF0ZSBieHAKcHJpbnQoZ2dwdWJyOjpnZ2JveHBsb3QoZGZfcGxvdCwgCiAgICAgICAgICAgICAgICAgICAgICAgIHggPSAidHVtb3JfZGVzY3JpcHRvciIsIAogICAgICAgICAgICAgICAgICAgICAgICB5ID0gImxvZzEwX3RtYiIsIAogICAgICAgICAgICAgICAgICAgICAgICBjb2xvciA9ICJWYXJpYW50X0NsYXNzaWZpY2F0aW9uIiwKICAgICAgICAgICAgICAgICAgICAgICAgcGFsZXR0ZSA9IHBhbGV0dGUpICsKICAgICAgICB0aGVtZV9QdWJsaWNhdGlvbigpICsgCiAgICAgICAgc2NhbGVfeV9jb250aW51b3VzKGxpbWl0cyA9IGMoMCwgeWxpbSkpICsKICAgICAgICB4bGFiKCJUaW1lcG9pbnQiKSArCiAgICAgICAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCkpKQoKIyBTYXZlIHRoZSBwbG90Cmdnc2F2ZShmaWxlbmFtZSA9ICJBbHRlcmF0aW9uX3R5cGVfdGltZXBvaW50cy5wZGYiLCAKICAgICAgIHBhdGggPSBwbG90c19kaXIsIAogICAgICAgd2lkdGggPSAxNSwgCiAgICAgICBoZWlnaHQgPSA4LCAKICAgICAgIGRldmljZSA9ICJwZGYiLCAKICAgICAgIHVzZURpbmdiYXRzID0gRkFMU0UpCmBgYAoKCiMgV2hhdCB0eXBlIG9mIGFsdGVyYXRpb25zIHdlIG9ic2VydmUgcGVyIHR1bW9yIGRlc2NyaXB0b3IgaW4gZWFjaCBjYW5jZXIgZ3JvdXA/CgpgYGB7ciBwbG90LWNnLWlkLCBmaWcud2lkdGggPSAyNSwgZmlnLmhlaWdodCA9IDE4LCBmaWcuZnVsbHdpZHRoID0gVFJVRX0KIyBDcmVhdGUgYnhwCnByaW50KGdncHVicjo6Z2dib3hwbG90KGRmX3Bsb3QsIAogICAgICAgICAgICAgICAgICAgICAgICB4ID0gInR1bW9yX2Rlc2NyaXB0b3IiLCAKICAgICAgICAgICAgICAgICAgICAgICAgeSA9ICJsb2cxMF90bWIiLCAKICAgICAgICAgICAgICAgICAgICAgICAgY29sb3IgPSAiVmFyaWFudF9DbGFzc2lmaWNhdGlvbiIsCiAgICAgICAgICAgICAgICAgICAgICAgIHBhbGV0dGUgPSBwYWxldHRlKSArCiAgICAgICAgZmFjZXRfd3JhcCh+Y2dfaWQpICsKICAgICAgICB0aGVtZV9QdWJsaWNhdGlvbigpICsgCiAgICAgICAgeGxhYigiVGltZXBvaW50IikgKwogICAgICAgIHNjYWxlX3lfY29udGludW91cyhsaW1pdHMgPSBjKDAsIHlsaW0pKSArCiAgICAgICAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCkpKQoKIyBTYXZlIHRoZSBwbG90Cmdnc2F2ZShmaWxlbmFtZSA9ICJBbHRlcmF0aW9uX3R5cGVfY2FuY2VyX2dyb3VwLnBkZiIsIAogICAgICAgcGF0aCA9IHBsb3RzX2RpciwgCiAgICAgICB3aWR0aCA9IDI1LCAKICAgICAgIGhlaWdodCA9IDE4LCAKICAgICAgIGRldmljZSA9ICJwZGYiLCAKICAgICAgIHVzZURpbmdiYXRzID0gRkFMU0UpCmBgYAoKCiMgV2hhdCB0eXBlIG9mIGFsdGVyYXRpb25zIHdlIG9ic2VydmUgcGVyIHR1bW9yIGRlc2NyaXB0b3IgaW4gZWFjaCBjYW5jZXIgZ3JvdXAgZGVmaW5lZCBieSBjZ0dGQUM/CgpgYGB7ciBwbG90LWNnR0ZBQy1uLCBmaWcud2lkdGggPSAxNCwgZmlnLmhlaWdodCA9IDgsIGZpZy5mdWxsd2lkdGggPSBUUlVFfQpkZl9wbG90X2NnR0ZBQyA8LSBkZl9wbG90ICU+JSAKICBhcnJhbmdlKHR1bW9yX2Rlc2NyaXB0b3JfY2dHRkFDX24pCiAgI211dGF0ZSh0dW1vcl9kZXNjcmlwdG9yX2NnR0ZBQ19uID0gZmFjdG9yKHR1bW9yX2Rlc2NyaXB0b3JfY2dHRkFDX24pKSAKCiNkZl9wbG90X2NnR0ZBQyR0dW1vcl9kZXNjcmlwdG9yX2NnR0ZBQ19uICU+JSBsZXZlbHMoKQoKIyBDcmVhdGUgYnhwCnByaW50KGdncHVicjo6Z2dib3hwbG90KGRmX3Bsb3RfY2dHRkFDLCAKICAgICAgICAgICAgICAgICAgICAgICAgeCA9ICJ0dW1vcl9kZXNjcmlwdG9yX2NnR0ZBQ19uIiwgCiAgICAgICAgICAgICAgICAgICAgICAgIHkgPSAibG9nMTBfdG1iIiwgCiAgICAgICAgICAgICAgICAgICAgICAgIGNvbG9yID0gIlZhcmlhbnRfQ2xhc3NpZmljYXRpb24iLAogICAgICAgICAgICAgICAgICAgICAgICBwYWxldHRlID0gcGFsZXR0ZSkgKwogICAgICAgIHRoZW1lX1B1YmxpY2F0aW9uKCkgKyAKICAgICAgICB4bGFiKCJUaW1lcG9pbnQiKSArCiAgICAgICAgc2NhbGVfeV9jb250aW51b3VzKGxpbWl0cyA9IGMoMCwgeWxpbSkpICsKICAgICAgICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwKSkpCgojIFNhdmUgdGhlIHBsb3QKZ2dzYXZlKGZpbGVuYW1lID0gIkFsdGVyYXRpb25fdHlwZV9jZ0dGQUMucGRmIiwgCiAgICAgICBwYXRoID0gcGxvdHNfZGlyLCAKICAgICAgIHdpZHRoID0gMTQsIAogICAgICAgaGVpZ2h0ID0gOCwgCiAgICAgICBkZXZpY2UgPSAicGRmIiwgCiAgICAgICB1c2VEaW5nYmF0cyA9IEZBTFNFKQoKYGBgCgoKYGBge3IgcGxvdC1jZ0dGQUMtbi1pbmRpdmlkdWFsLXBsb3RzLCBmaWcud2lkdGggPSA4LCBmaWcuaGVpZ2h0ID0gNiwgZmlnLmZ1bGx3aWR0aCA9IFRSVUV9CmNnR0ZBQ19pZCA8LSBhcy5jaGFyYWN0ZXIodW5pcXVlKGRmX3Bsb3RfY2dHRkFDJGNnR0ZBQykpCmNnR0ZBQ19pZAoKIyBMb29wIHRocm91Z2ggdmFyaWFibGUKZm9yIChpIGluIHNlcV9hbG9uZyhjZ0dGQUNfaWQpKXsKICBwcmludChpKQogIGRmX3N1YiA8LSBkZl9wbG90X2NnR0ZBQyAlPiUKICAgICAgZmlsdGVyKGNnR0ZBQyA9PSBjZ0dGQUNfaWRbaV0pCgogIAogICAjIENyZWF0ZSBieHAKICBwcmludChnZ3B1YnI6OmdnYm94cGxvdChkZl9zdWIsIAogICAgICAgICAgICAgICAgICAgICAgICB4ID0gInR1bW9yX2Rlc2NyaXB0b3JfY2dHRkFDX24iLCAKICAgICAgICAgICAgICAgICAgICAgICAgeSA9ICJsb2cxMF90bWIiLCAKICAgICAgICAgICAgICAgICAgICAgICAgY29sb3IgPSAiVmFyaWFudF9DbGFzc2lmaWNhdGlvbiIsCiAgICAgICAgICAgICAgICAgICAgICAgIHBhbGV0dGUgPSBwYWxldHRlKSArCiAgICAgICAgdGhlbWVfUHVibGljYXRpb24oKSArIAogICAgICAgIGxhYnModGl0bGUgPSBwYXN0ZShjZ0dGQUNfaWRbaV0pKSArCiAgICAgICAgc2NhbGVfeV9jb250aW51b3VzKGxpbWl0cyA9IGMoMCwgeWxpbSkpICsKICAgICAgICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwLCB2anVzdCA9IDAuNSwgaGp1c3QgPSAxKSkpCn0KYGBgCgojIFdoYXQgdHlwZSBvZiBhbHRlcmF0aW9ucyB3ZSBvYnNlcnZlIHBlciB0dW1vciBkZXNjcmlwdG9yIGluIGVhY2ggY2FuY2VyIGdyb3VwIChhZGQgX24pKT8KIAoKYGBge3IgcGxvdC1uLCBmaWcud2lkdGggPSAxMiwgZmlnLmhlaWdodCA9IDgsIGZpZy5mdWxsd2lkdGggPSBUUlVFfQpjZyA8LSBhcy5jaGFyYWN0ZXIodW5pcXVlKGRmX3Bsb3QkY2dfaWQpKQpjZwoKIyBMb29wIHRocm91Z2ggdmFyaWFibGUKZm9yIChpIGluIHNlcV9hbG9uZyhjZykpewogIHByaW50KGkpCiAgZGZfc3ViIDwtIGRmX3Bsb3QgJT4lCiAgICAgIGZpbHRlcihjZ19pZCA9PSBjZ1tpXSkKICAKICAjIENyZWF0ZSBieHAKICBwcmludChnZ3B1YnI6OmdnYm94cGxvdChkZl9zdWIsIAogICAgICAgICAgICAgICAgICAgICAgICB4ID0gInR1bW9yX2Rlc2NyaXB0b3JfY2dfbiIsIAogICAgICAgICAgICAgICAgICAgICAgICB5ID0gImxvZzEwX3RtYiIsIAogICAgICAgICAgICAgICAgICAgICAgICBjb2xvciA9ICJWYXJpYW50X0NsYXNzaWZpY2F0aW9uIiwKICAgICAgICAgICAgICAgICAgICAgICAgcGFsZXR0ZSA9IHBhbGV0dGUpICsKICAgICAgICB0aGVtZV9QdWJsaWNhdGlvbigpICsgCiAgICAgICAgeGxhYigiVGltZXBvaW50IikgKwogICAgICAgIGxhYnModGl0bGUgPSBwYXN0ZShjZ1tpXSkpICsKICAgICAgICBzY2FsZV95X2NvbnRpbnVvdXMobGltaXRzID0gYygwLCB5bGltKSkgKwogICAgICAgIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTAsIHZqdXN0ID0gMC41LCBoanVzdCA9IDEpKSkKfQpgYGAKCgojIFdoYXQgdHlwZSBvZiBhbHRlcmF0aW9ucyB3ZSBvYnNlcnZlIHBlciB0dW1vciBkZXNjcmlwdG9yIGluIGVhY2ggY2FuY2VyIGdyb3VwIGFuZCB0aW1lcG9pbnQgbW9kZWw/CgpgYGB7ciBwbG90LXRpbWVwb2ludC1tb2RlbCwgZmlnLndpZHRoID0gMjUsIGZpZy5oZWlnaHQgPSAxOCwgZmlnLmZ1bGx3aWR0aCA9IFRSVUV9CnRtIDwtIGFzLmNoYXJhY3Rlcih1bmlxdWUoZGZfcGxvdCR0aW1lcG9pbnRzX21vZGVscykpCnRtCgojIExvb3AgdGhyb3VnaCB2YXJpYWJsZQpmb3IgKGkgaW4gc2VxX2Fsb25nKHRtKSl7CiAgcHJpbnQoaSkKICBkZl9zdWIgPC0gZGZfcGxvdCAlPiUKICAgICAgZmlsdGVyKHRpbWVwb2ludHNfbW9kZWxzID09IHRtW2ldKQogIAogICMgQ3JlYXRlIGJ4cAogIHByaW50KGdncHVicjo6Z2dib3hwbG90KGRmX3N1YiwgCiAgICAgICAgICAgICAgICAgICAgICAgIHggPSAidHVtb3JfZGVzY3JpcHRvciIsIAogICAgICAgICAgICAgICAgICAgICAgICB5ID0gInRtYiIsIAogICAgICAgICAgICAgICAgICAgICAgICBjb2xvciA9ICJWYXJpYW50X0NsYXNzaWZpY2F0aW9uIiwKICAgICAgICAgICAgICAgICAgICAgICAgcGFsZXR0ZSA9IHBhbGV0dGUpICsKICAgICAgICBmYWNldF93cmFwKH5jYW5jZXJfZ3JvdXApICsKICAgICAgICB0aGVtZV9QdWJsaWNhdGlvbigpICsKICAgICAgICB5bGFiKCJUTUIiKSArCiAgICAgICAgeGxhYigiVGltZXBvaW50IikgKwogICAgICAgIHNjYWxlX3lfY29udGludW91cyhsaW1pdHMgPSBjKDAsIHlsaW0pKSArCiAgICAgICAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCkpKQp9CmBgYAoKCmBgYHtyIGVjaG89VFJVRX0Kc2Vzc2lvbkluZm8oKQpgYGAK